﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;

namespace Jobping.ShortUrls.Models
{
	/// <summary>
	///     This is the hard of the project. A class that maps a number to a short text encoding of that number
	///     Of course we also need to decode that text into a number.
	/// </summary>
	public class ShortUrlEncoder
	{
		//These are our allowed characters for the url
		//private const string URL_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-";
		private const string URL_CHARS =   "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ1234567890_-"; //Remove vowels so nasty words dont get formed. a e i o u

		//This is theh length of our allowed characters, also used as the base for our encoding
		private static readonly long URL_CHARS_LENGTH = URL_CHARS.Length;

		//Just maps the each char in our URL_CHARS to the position of that char
		private static readonly Dictionary<char, int> reverse = new Dictionary<char, int>();

		static ShortUrlEncoder()
		{
			//Setup the reverse dictionary
			for (int i = 0; i < URL_CHARS.Length; i++)
				reverse.Add(URL_CHARS[i], i);
		}

		/// <summary>
		///     Function to encode a number into a shorter string
		///     e.g turns 103892092010 into "Xiy"
		/// </summary>
		/// <param name="number">The number to encode</param>
		/// <returns>The short text version of the number</returns>
		public string Encode(long number)
		{
			StringBuilder sb = new StringBuilder();
			int remainder;

			while (number > 0)
			{
				remainder = (int)(number % URL_CHARS_LENGTH);
				number = number / URL_CHARS_LENGTH;

				sb.Append(URL_CHARS[remainder]);
			};

			return sb.ToString();
		}

		/// <summary>
		///     Function to decode a short string into a number
		///     e.g turns "Xiy" into 103892092010
		/// </summary>
		/// <param name="text">The text to decode</param>
		/// <returns>The number represented by the short text</returns>
		[Obsolete("Just search the db for the short url, leaving here for testing purposes")]
		public long Decode(string text)
		{
			long result = 0;

			for (int i = 0; i < text.Length; i++)
			{
				int charIndex = reverse[text[i]];
				var powResult = (long)Math.Pow(URL_CHARS_LENGTH, i);
				result += charIndex * powResult;
			}

			return result;
		}
	}
}